from Entities.Calendars.Holiday import Holiday 
from datetime import date
from datetime import timedelta

class MoveableHoliday (Holiday):
    
    def __init__ (self, description, offset):
        Holiday.__init__(self, description)       
        self.delta   = timedelta (days=offset)
    
    @staticmethod
    def easter (gyear):
        year = gyear
        g = year % 19
        century = year/100
        h = (century-century/4-(8*century+13)/25+19*g+15)%30
        i = h-(h/28)*(1-(h/28)*(29/(h+1))*((21-g)/11))
        j = (year+year/4+i+2-century+century/4)%7
        p = i-j
        day = 1+(p+27+(p+6)/40)%31
        month = 3+(p+26)/30
        return date(year,month,day)
    
    
    def __repr__(self):
        return "<MoveableHoliday(%d)>" % (self.offset)

    def isholiday (self, when):
        return when == (MoveableHoliday.easter (when.year) + self.delta)
    
    def text (self):
        if self.delta.days < 0:
            return "easter-%d" % self.delta.days
        if self.delta.days > 0:
            return "easter+%d" % self.delta.days
        return "easter"
    
    @staticmethod 
    def ShroveMonday ():
        return MoveableHoliday ("Shrove Monday", -48)

    @staticmethod 
    def ShroveTuesday ():
        return MoveableHoliday ("Shrove Tuesday", -47)

    @staticmethod 
    def AshWednesday ():
        return MoveableHoliday ("Ash Wednesday", -47)

    @staticmethod 
    def PassionSunday ():
        return MoveableHoliday ("Passion Sunday", -14)

    @staticmethod 
    def PalmSunday ():
        return MoveableHoliday ("Palm Sunday", -7)

    @staticmethod 
    def MaundyThursday ():
        return MoveableHoliday ("Maundy Thursday", -3)
        
    @staticmethod 
    def GoodFriday ():
        return MoveableHoliday ("Good Friday", -2)

    @staticmethod 
    def Easter():
        return MoveableHoliday ("Easter", 0)

    @staticmethod 
    def EasterMonday ():
        return MoveableHoliday ("Easter Monday", 1)

    @staticmethod 
    def RogationSunday ():
        return MoveableHoliday ("Easter Monday", 35)
                
    @staticmethod 
    def Ascension ():
        return MoveableHoliday ("Ascension", 39)

    @staticmethod 
    def Pentecost ():
        return MoveableHoliday ("Pentecost", 49)
                
    @staticmethod 
    def WhitMunday ():
        return MoveableHoliday ("Whit Munday", 50)

    @staticmethod 
    def TrinitySunday ():
        return MoveableHoliday ("Trinity Sunday", 56)

    @staticmethod 
    def CorpusChristi ():
        return MoveableHoliday ("Corpus Christi", 60)
                                                